/*
Copyright SecureKey Technologies Inc. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package event

import (
	"testing"
	"time"

	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/client/chain"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/client/event"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/client/iam"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/core/config"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/ichain_sdk"
	iam2 "git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/iam"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/test/data"
	"github.com/pkg/errors"
	"github.com/stretchr/testify/assert"
)

func TestFilterEvent(t *testing.T) {
	env := data.GetEnvFromFlag()
	assert.NotNil(t, env)
	sdk, err := ichain_sdk.New(config.FromBuilder(env.SdkBuilder()))
	assert.NoError(t, err)
	defer sdk.Close()

	iamClient, err := iam.New(sdk.Context())
	assert.NoError(t, err)
	identity, err := iamClient.CreateSigningIdentity(iam2.WithCert(env.ClientCert()),
		iam2.WithPrivateKey(env.ClientPvk()))

	eventClient, err := event.New(sdk.ChainContext(env.ChainId(), ichain_sdk.WithIdentity(identity)))
	reg, ch, err := eventClient.RegisterFilteredBlockEvent()
	assert.NoError(t, err)
	defer eventClient.Unregister(reg)

	chainClient, err := chain.New(sdk.ChainContext(env.ChainId(), ichain_sdk.WithIdentity(identity)))
	assert.NoError(t, err)

	timeout := time.NewTimer(3 * time.Second)

	go func() {
		_, err = chainClient.Execute(env.RandInvokeFunc())
		assert.NoError(t, err)
	}()

	select {
	case block := <-ch:
		assert.NotEmpty(t, block.FilteredBlock.FilteredTransactions)
		return
	case <-timeout.C:
		assert.NoError(t, errors.New("timeout"))
		return
	}
}

func TestCompleteEvent(t *testing.T) {
	env := data.GetEnvFromFlag()
	assert.NotNil(t, env)
	sdk, err := ichain_sdk.New(config.FromBuilder(env.SdkBuilder()))
	assert.NoError(t, err)
	defer sdk.Close()

	iamClient, err := iam.New(sdk.Context())
	assert.NoError(t, err)
	identity, err := iamClient.CreateSigningIdentity(iam2.WithCert(env.ClientCert()),
		iam2.WithPrivateKey(env.ClientPvk()))

	eventClient, err := event.New(sdk.ChainContext(env.ChainId(), ichain_sdk.WithIdentity(identity)), event.WithBlockEvents())
	reg, ch, err := eventClient.RegisterBlockEvent()
	assert.NoError(t, err)
	defer eventClient.Unregister(reg)

	chainClient, err := chain.New(sdk.ChainContext(env.ChainId(), ichain_sdk.WithIdentity(identity)))
	assert.NoError(t, err)

	timeout := time.NewTimer(3 * time.Second)

	go func() {
		_, err = chainClient.Execute(env.RandInvokeFunc())
		assert.NoError(t, err)
	}()

	select {
	case block := <-ch:
		assert.NotEmpty(t, block.Block.GetData().GetData())
		return
	case <-timeout.C:
		assert.NoError(t, errors.New("timeout"))
		return
	}
}
